/*******************************************************************************
 ** File name           ：Wiegand.h
 ** Last update date    ：2021/5/19
 ** Author              ：licl
 ** Usage               ：用于韦根协议数据解析发送
 ********************************************************************************
*/
#ifndef _Wiegand_H
#define _Wiegand_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdint.h>

#define WiegandReceiveDataBuffcnt 3U

#define DATA_HOLD_TIME 15U
#define DATA_INTERVAL_TIME 2U

    typedef enum
    {
        Wiegand26,
        Wiegand34,
        WiegandNone,
        WiegandIllegal

    } WiegandDataType_E;

    typedef enum
    {
        HIGH,
        LOW

    } WiegandGPIOLevel_E;
    typedef enum
    {
        OUT0,
        OUT1

    } WiegandGPIONumber;

    typedef enum
    {
        UNUSED,
        USED
    } DataUseFlag_E;

    typedef struct
    {
        uint8_t data[5]; //暂时支持韦根34/26位 5*8=40;
        uint8_t writeBitcnt;
        uint8_t cnt;
        DataUseFlag_E flag;
    } WiegandData_S;

    typedef struct
    {
        uint16_t hid;
        uint16_t pid;
        WiegandDataType_E dataType;
    } Wiegand_Valid_data_S;

    typedef Wiegand_Valid_data_S (*getWiegandData)(void);
    typedef void (*HardwareInit)(void);
    typedef int (*wiegand_push_data1)(void);
    typedef int (*wiegand_push_data0)(void);
    typedef void (*data_received_over)(void);
    typedef Wiegand_Valid_data_S (*get_wiegand_data)(void);

    typedef int (*wiegand_send_data)(Wiegand_Valid_data_S);
    typedef void (*wiegand_delay_us)(uint32_t);
    typedef void (*wiegand_delay_ms)(uint32_t);
    typedef void (*wiegand_timer_start_ms)();
    typedef void (*wiegand_timer_stop)();
    typedef void (*wiegand_gpio_output)(void);

#define close_interrupts
#define open_interrupts

    typedef struct
    {
        WiegandData_S WiegandReceiveData[WiegandReceiveDataBuffcnt];
        HardwareInit input_gpio_int;
        wiegand_push_data1 input_data_1;
        wiegand_push_data0 input_data_0;
        data_received_over data_received_done; //每次 push 数据后 50ms 回调此函数，如果持续接受数据 就每次更更新回调的时间为50ms

        get_wiegand_data get_data;
        wiegand_timer_start_ms timer_start_ms;
        wiegand_timer_stop timer_stop;

        HardwareInit output_gpio_int;
        wiegand_delay_ms delay_ms;
        wiegand_delay_us delay_us;

        wiegand_gpio_output d0_output0;
        wiegand_gpio_output d0_output1;
        wiegand_gpio_output d1_output0;
        wiegand_gpio_output d1_output1;

        wiegand_send_data send_data;

        uint8_t write;
        /* data */
    } Wiegand_S;

    int init_wiegand(
        HardwareInit wiegand_in,
        HardwareInit wiegand_out,
        wiegand_delay_us delay_us,
        wiegand_delay_ms delay_ms,
        wiegand_timer_start_ms timer_start,
        wiegand_timer_stop timer_stop,
        wiegand_gpio_output gpio_0_out0,
        wiegand_gpio_output gpio_0_out1,
        wiegand_gpio_output gpio_1_out0,
        wiegand_gpio_output gpio_1_out1);
    int wiegand_input_1();
    int wiegand_input_0();
    void check_received_over();
#ifdef __cplusplus
}
#endif

#endif
